#include "TaskQueue.h"

using namespace tp;

TaskQueue::TaskQueue(int size)
    :_size(size)
     ,_mutex()
     ,_notFull(_mutex)
     ,_notEmpty(_mutex)
     ,_isRunning(true)
{}

TaskQueue::~TaskQueue()
{}

void TaskQueue::push(const Func& func)
{
    tp::MutexLockGuard mlg(_mutex);
    while (full())
    {
        _notFull.wait();
    }

    _que.push(func);
    _notEmpty.notify();
}

void TaskQueue::wakeup()
{
    _isRunning = false;
    _notEmpty.notifyall();    
}

TaskQueue::Func TaskQueue::pop()
{
    tp::MutexLockGuard mlg(_mutex);
    while (empty() && _isRunning)
    {
        _notEmpty.wait();
    }

    if (!_isRunning)
    {
        return NULL;
    }

    Func func = _que.front();
    _que.pop();
    _notFull.notify();

    return func;
}

bool TaskQueue::full()
{
    return _que.size() >= _size;
}

bool TaskQueue::empty()
{
    return _que.empty();
}
